package com.AES;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.JFrame;
import javax.swing.JProgressBar;

public class EncodeFile extends JFrame implements Runnable
{

    private static final long serialVersionUID=-2182212345964453619L;
    private JFrame frame;
    private JProgressBar progressBar=new JProgressBar();;
    private String key;
    private InputStream is;
    private OutputStream os;
    private String choice;
    private File fi;

    public EncodeFile(String choice, String key, InputStream is,
	    OutputStream os, File f)
    {
	this.fi=f;
	this.key=key;
	this.is=is;
	this.os=os;
	this.choice=choice;
	frame=new JFrame();
	frame.setBounds(100,100,301,79);
	frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
	frame.getContentPane().setLayout(null);
	frame.getContentPane().add(progressBar);
	progressBar.setBounds(14,13,267,17);
	progressBar.setStringPainted(true);
	progressBar.setValue(0);
	progressBar.setMaximum(100);
	frame.setLocationRelativeTo(null);
	frame.setVisible(true);
	frame.setResizable(false);

    }

    private void encrypt(String key, InputStream is, OutputStream os)
	    throws Throwable
    {
	encryptOrDecrypt(key,Cipher.ENCRYPT_MODE,is,os);
    }

    private void decrypt(String key, InputStream is, OutputStream os)
	    throws Throwable
    {
	encryptOrDecrypt(key,Cipher.DECRYPT_MODE,is,os);
    }

    private void encryptOrDecrypt(String key, int mode, InputStream is,
	    OutputStream os) throws Throwable
    {
	// DESedeKeySpec dks=new DESedeKeySpec(key.getBytes()); at least 24 byte
	// DESKeySpec dks = new DESKeySpec(key.getBytes()); at least 8 byte
	SecretKeySpec dks=new SecretKeySpec(key.getBytes(),"DES");
	SecretKeyFactory skf=SecretKeyFactory.getInstance("DES");
	SecretKey desKey=skf.generateSecret(dks);
	Cipher cipher=Cipher.getInstance("DES"); // DES/ECB/PKCS5Padding for
						 // SunJCE

	if(mode==Cipher.ENCRYPT_MODE)
	{
	    cipher.init(Cipher.ENCRYPT_MODE,desKey);
	    CipherInputStream cis=new CipherInputStream(is,cipher);
	    doCopy(cis,os);
	}
	else if(mode==Cipher.DECRYPT_MODE)
	{
	    cipher.init(Cipher.DECRYPT_MODE,desKey);
	    CipherOutputStream cos=new CipherOutputStream(os,cipher);
	    doCopy(is,cos);
	}
    }

    private void doCopy(InputStream is, OutputStream os) throws IOException
    {
	byte[] bytes=new byte[256];
	int numBytes;
	int currentValue;
	long totalBytes=fi.length();
	long byteRead=0;

	while ((numBytes=is.read(bytes))!=-1)
	{
	    os.write(bytes,0,numBytes);
	    byteRead=numBytes+byteRead;
	    currentValue=(int)(byteRead*100/totalBytes);
	    progressBar.setValue(currentValue);
	}
	os.flush();
	os.close();
	is.close();
    }

    public void run()
    {
	try
	{
	    if(choice.equals("e"))
		encrypt(key,is,os);
	    else
		decrypt(key,is,os);
	}
	catch (Throwable e)
	{
	    e.printStackTrace();
	}
    }
}
